using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.Extensions.Configuration;
using MongoDB.Bson;
using MongoDB.Driver;

namespace microsoft_TODO.MongoCore.Repositories
{
    public class BaseRepository<T>
    {
        protected IMongoCollection<T> Collection;
        protected IMongoCollection<BsonDocument> BsonCollection;
        public BaseRepository(IConfiguration configuration, string collectionName)
        {
            var connStr = configuration.GetConnectionString("Mongo"); // 连接需要认证，通过一条语句并指定了数据表
            var client = new MongoClient(connStr);
            var db = client.GetDatabase("todo");
            Collection = db.GetCollection<T>(collectionName);
            BsonCollection = db.GetCollection<BsonDocument>(collectionName);
        }

        public T Insert(T entity)
        {
            this.Collection.InsertOne(entity);
            return entity;
        }

        public T FirstOrDefault(Expression<Func<T, bool>> exp)
        {
            return this.Collection.Find(exp).FirstOrDefault();
        }

        public List<T> GetAllList(Expression<Func<T, bool>> exp = null)
        {
            return exp == null
              ? this.Collection.AsQueryable().ToList()
              : this.Collection.Find(exp).ToList();
        }

        public IQueryable<T> GetAll()
        {
            return this.Collection.AsQueryable();
        }

        public void Update(Expression<Func<T, bool>> exp, UpdateDefinition<T> update)
        {
            this.Collection.UpdateMany(exp, update);
        }

        public void Upsert(Expression<Func<T, bool>> exp, UpdateDefinition<T> update)
        {
            this.Collection.UpdateMany(exp, update, new UpdateOptions { IsUpsert = true });
        }

        public bool Delete(Expression<Func<T, bool>> exp)
        {
            return this.Collection.DeleteMany(exp).DeletedCount > 0;
        }

        public long Count(Expression<Func<T, bool>> exp)
        {
            return this.Collection.Count(exp);
        }

        public bool IsExistent(Expression<Func<T, bool>> exp)
        {
            return this.Collection.Find(exp).Any();
        }
    }
}
